package com.flyme.module.file.provider.controller;


import com.flyme.common.core.constants.SettingConstant;
import com.flyme.common.core.model.ResultBody;
import com.flyme.common.core.utils.ApiAssert;
import com.flyme.common.core.utils.IpInfoUtil;
import com.flyme.common.core.utils.ObjectUtils;
import com.flyme.core.base.limit.RedisRaterLimiter;
import com.flyme.core.base.supper.controller.BaseController;
import com.flyme.core.base.supper.entity.EntityMap;
import com.flyme.module.file.client.api.SysFileRemoteService;
import com.flyme.module.file.client.entity.SysFile;
import com.flyme.module.file.client.vo.OssSetting;
import com.flyme.module.file.provider.service.SysFileService;
import com.flyme.module.file.provider.utils.AliOssUtil;
import com.flyme.module.file.provider.utils.FileUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Map;

/**
 * @author flyme
 */
@Slf4j
@Api(tags = "文件管理")
@RestController
public class SysFileController extends BaseController<SysFileService, SysFile> implements SysFileRemoteService {

    @Autowired
    private RedisRaterLimiter redisRaterLimiter;
    @Autowired
    private AliOssUtil aliOssUtil;
    @Autowired
    private FileUtil fileUtil;
    @Autowired
    private IpInfoUtil ipInfoUtil;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private SysFileService fileService;

    @PostMapping("/file/upload")
    @ApiOperation(value = "文件上传")
    public ResultBody<Map<String, Object>> upload(@RequestParam(name = "file") MultipartFile file, HttpServletRequest request) {

        redisTemplate.opsForValue().set(SettingConstant.ALI_OSS,"{\"bucket\":\"cbstudy\",\"endpoint\":\"oss-cn-shenzhen.aliyuncs.com\",\"secretKey\":\"93QYRInZ8wYfPvi0cwbovjnvnWIS39\",\"accessKey\":\"LTAIdBOeU021BuTh\",\"http\":\"http://\",\"serviceName\":\"ALI_OSS\",\"changed\":false}");
        redisTemplate.opsForValue().set(SettingConstant.OSS_USED,"ALI_OSS");
        redisTemplate.opsForValue().set(SettingConstant.LOCAL_OSS,"{\"endpoint\":\"127.0.0.1:9999/base/file/view\",\"filePath\":\"D:/upload\",\"http\":\"http://\",\"serviceName\":\"LOCAL_OSS\"}");
        // IP限流 在线Demo所需 5分钟限1个请求
        // String token = redisRaterLimiter.acquireTokenFromBucket("upload:" + ipInfoUtil.getIpAddr(request), 100, 300000);
        String fileType = ObjectUtils.getParameter("fileType", "image");//文件类型
        // ApiAssert.notNull("上传那么多干嘛，等等再传吧", token);
        String used = redisTemplate.opsForValue().get(SettingConstant.OSS_USED);
        ApiAssert.notNull("您还未配置OSS服务", used);
        String result = "";
        String fKey = ObjectUtils.renamePic(file.getOriginalFilename());
        SysFile f = new SysFile();
        EntityMap map = new EntityMap();
        try {
            FileInputStream inputStream = (FileInputStream) file.getInputStream();
            // 上传至第三方云服务或服务器
            if (used.equals(SettingConstant.ALI_OSS)) {
                if (fileType.equals("image") || fileType.equals("apk")) {
                    //上传OSS
                    result = aliOssUtil.aliInputStreamUpload(inputStream, fKey);
                    f.setOssPath(result);
                } else {
                    result = fileUtil.localUpload(file, fKey);
                    f.setLocalPath(result);
                }
                f.setStoreType(SettingConstant.OSS_ALI);
            }
            if (used.equals(SettingConstant.LOCAL_OSS)) {
                result = fileUtil.localUpload(file, fKey);
                f.setLocalPath(result);
                f.setStoreType(SettingConstant.OSS_LOCAL);
            }
            // 保存数据信息至数据库
            f.setFileName(file.getOriginalFilename());
            f.setFileSize(file.getSize());
            f.setFileType(file.getContentType());
            f.setFileKey(fKey);
            fileService.save(f);

        } catch (Exception e) {
            log.error(e.toString());
            return ResultBody.error().setInfo(e.toString());
        }
        if (used.equals(SettingConstant.LOCAL_OSS)) {
            OssSetting os = fileUtil.getOssSetting();
            result = os.getHttp() + os.getEndpoint() + "/" + f.getId();
        }
        if (used.equals(SettingConstant.ALI_OSS)) {
            if (fileType.equals("video")) {
                //视频文件预览地址
                result = "http://" + "api.cbstudy.com/base/file/view" + "/" + f.getId();
            }
        }
        map.put("fileUrl", result);
        map.put("fileId", f.getId());
        return ResultBody.success().setData(map);
    }

    @GetMapping(value = "/file/view/{id}")
    @ApiOperation(value = "本地存储预览文件")
    @CrossOrigin
    public void view(@PathVariable String id, HttpServletResponse response) throws IOException {
        SysFile file = fileService.getById(id);
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(file.getFileKey(), "UTF-8"));
        response.addHeader("Content-Length", file.getFileSize().toString());
        response.setContentType("application/octet-stream;charset=UTF-8");
        if (ObjectUtils.isNotEmpty(file.getLocalPath())) {
            fileUtil.view(file.getLocalPath(), response);
        }
    }
}
